vlwkaos' digital garden

Rust - print macro, functions, code blocks

  • println!
  • function, semi-colon
  • mutable(mut), shadowing
  • memory + reference

println!

  • macro = 코드를 짜는 코드 (metaprogram)
    • 컴파일러가 해석하기 전에 코드가 확장된다.
    • 함수는 컴파일 시간에 코드 작성을 못함
  • println 코드
macro_rules! format_args {
    ($fmt : expr) => { ... };
    ($fmt : expr, $($args : tt) *) => { ... };
}
  • println macro의 기능을 살펴보기
fn main() {
    let str = "Bye";
    println!("Hello, world!");
    // eprintln! for error / progress
    println!("{} {}", 1, 2); // 1 2

    // 1.58 버전부터는 다음 포맷인식 가능
    println!("{str}"); // Bye
    // 지금은 아래처럼 연결해줄 수 있다
    println!("{s}", s = str); // Bye

    // 몇번째 인자를 포맷에 쓸지 정할 수 있다.
    println!("{0} {0} {1}", 1, 2) // 1 1 2
}

print trait(shared func)

  • Display 마치 Java의 toString
  • Debug print {:?} 속성 등을 보여줌
  • Pretty print {:#?}
fn main() {
    // 어떻게 출력해야할 지 모름   
    println!("{}", ()); // `()` doesn't implement `std::fmt::Display`

    // raw text 그대로 출력
    println!(r#"\n"#);  // \n 
    // 라인 별로 출력됨    
println!(
"abcd
asdf
asdf"); 

    println!("{:b}", 2); // binary
    println!("{:X}", 4); // hex

    let va = 9;
    println!("{:p}", va); // pointer의 위치를 print : error
    println!("{:p}", &9); // ok

    // < ^ > text align
    // pad with -, ^ center, 30 chars long
    println!("{:-^30}", 10); 
    println!("{v:0<15}", v = va);
}

functions, code blocks

  • rust는 expression-based language
  • void가 아닌 빈 tuple을 반환 (unit type)
// 함수 작성
fn give_age() -> i32 {
    42 // 세미 콜론 없으면 반환 return 42
    // 반환이 없을 때(void)는 empty tuple () type으로 반환된다
}

fn main() {
    let num = give_age();

    // main은 ()를 반환해야함 === void main
}

계속

fn give_number(one: i32, two: i32) -> i32 {
    one * two
}

fn num_fun(one: i16, two: i16) -> i16 {
    let sum_by_ten = {
        // scope 내에서 작동
        let first = 10;
        first + one + two // return
    };
    sum_by_ten
}

fn main() {
    let res = give_number(9, 8);
    println!("{}", res);
    println!("{}", num_fun(1,2));
}

mutable(mut), shadowing

  • rust는 기본적으로 불변형 mut을 선언해줘야 바꿀 수 있음
fn main() {
    let mut nm = 10;
    nm = 9;
}
  • 같은 이름 다시 선언하는 경우 스코프 내 절차적으로 사용
fn main() {
    let a = 10;
    let a = "AA"; // 여기부턴 이걸로
    {
        let a = 11;
        // a = 11
    }
    // a = "AA"
}

memory + references

  • stack
    • 제일 접근이 빠름, 그러나 컴파일 시점에 변수 크기를 알아야 스택에 올릴 수 있다.
  • heap
    • stack 보단 느리다. 메모리 특정이 안될때 일단 heap에 올리고, 여기 가르키는 포인터를 stack 에 저장
  • pointer
    • 책의 목차같은 역할
    • 보통 보는 건 reference
fn main() {
    let num = 15; // i32
    let ref1 = &num; // num은 데이터를 갖고있고, ref1은 값을 볼 수 있다. &i32
    let ref2 = &ref1; // &&i32
}

&String s pointing at String s1

Referred in

Rust - print macro, functions, code blocks